﻿using System.Collections.ObjectModel;
using System.Drawing;
using System.IO;
using System.Windows.Controls;
using Mapster;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Prism.Commands;
using Prism.Events;
using Prism.Regions;
using Prism.Services.Dialogs;
using SharpDX.Direct2D1;
using SixLabors.Fonts;
using SmartPlant.Core;
using SmartPlant.Core.Mvvm;
using SmartPlant.Core.View;
using SmartPlant.Model;
using SmartPlant.Model.Biz;
using SmartPlant.Model.DbContext;
using SmartPlant.Model.UI;
using SmartPlant.Modules.Base.UIEntity;
using SmartPlant.Modules.Base.Views;
using SmartPlant.Services;
using SmartPlant.Services.Interfaces;
using SmartPlant.WinCore;
using SmartPlant.WinCore.Helper;
using Telerik.Windows.Controls;
using Telerik.Windows.Documents.FormatProviders.Html.Parsing.Dom;
using Telerik.Windows.Documents.Model.Drawing.Charts;
using Telerik.Windows.Persistence.Core;
using Unity;
using static System.Formats.Asn1.AsnWriter;
using DialogParameters = Prism.Services.Dialogs.DialogParameters;

namespace SmartPlant.Modules.Base.ViewModels
{
    public class DomainExplorerViewModel : RegionViewModelBase
    {
        private decimal _proId;
        private TreeNodeModelList _nodes;
        private string _treeTitle = "工程数据(Domain Explorer)";
        private IProjectService _projectService;
        private IDrawingService _drawingService;
        private ILineService _lineServ;
        private IEquipService _equipServ;

        private ILoopService _loopService;
        private IInstrumentService _instrumentService;
        private ISpecSheetDataService _specServ;
        private IPanelService _panelServ;
        private IPlantGroupService _plantGroupService;
        private readonly IDialogService _dialogService;
        private IEventAggregator _eventAggregator;
        private readonly IRegionManager _regionManager = null;
        private ObservableCollection<ContextOperationModel> contextMenuItems = new ObservableCollection<ContextOperationModel>();
        private Plant _selectedPlant;

        public DomainExplorerViewModel(IEventAggregator eventAggregator, IRegionManager regionManager, IProjectService projectService, IUnityContainer unityContainer, IDialogService dialogService)
            : base(regionManager, unityContainer, dialogService)
        {
            this._regionManager = regionManager;
            _instrumentService = unityContainer.Resolve<InstrumentService>();
            _plantGroupService = unityContainer.Resolve<PlantGroupService>();
            _projectService = projectService;
            _lineServ = unityContainer.Resolve<LineService>();
            _specServ = unityContainer.Resolve<InstrumentService>();
            _loopService = unityContainer.Resolve<LoopService>();
            _drawingService = unityContainer.Resolve<DrawingService>();
            _equipServ = unityContainer.Resolve<EquipService>();
            _panelServ = unityContainer.Resolve<PanelService>();
            _dialogService = dialogService;
            _nodes = new TreeNodeModelList();
            _eventAggregator = eventAggregator;
            _eventAggregator.GetEvent<ReSelectProjectDomainEvent>().Subscribe(ReSelectProjectDomain);
            Plants = new ObservableCollection<Plant>();
            PlantSelectedCommand = new DelegateCommand<object>(PlantSelectedAsync);
            PreviewExpandCommand = new DelegateCommand<TreeNodeModel>(PreviewExpandAsync);
            ExcuteCommand = new DelegateCommand<object>(ExecContextMenu);
        }
        /// <summary>
        /// 右键菜单的内容
        /// </summary>
        public ObservableCollection<ContextOperationModel> ContextOperations
        {
            get { return this.contextMenuItems; }
            private set
            {
                if (this.contextMenuItems != value)
                {
                    this.contextMenuItems = value;
                    RaisePropertyChanged();
                }
            }
        }
        /// <summary>
        /// 选中的plant，会照此plant进行渲染树<see cref="InitTree(Plant)"/>
        /// </summary>
        public Plant selectedPlant
        {
            get { return _selectedPlant; }
            set { SetProperty(ref _selectedPlant, value); }
        }
        public string TreeTitle
        {
            get { return _treeTitle; }
            set { SetProperty(ref _treeTitle, value); }
        }

        /// <summary>
        /// xaml里树的数据源
        /// </summary>
        public TreeNodeModelList TreeNodes
        {
            get { return _nodes; }
            set { SetProperty(ref _nodes, value); }
        }

        private ObservableCollection<Plant> plants;

        /// <summary>
        /// 工厂列表
        /// </summary>
        public ObservableCollection<Plant> Plants
        {
            get { return plants; }
            set
            {
                plants = value;
                RaisePropertyChanged();
            }
        }

        private TreeNodeModel selectedNode;

        /// <summary>
        /// 选中的节点（可能是unit 可能是loop 可能是ins）
        /// </summary>
        public TreeNodeModel SelectedNode
        {
            get { return selectedNode; }
            set
            {
                selectedNode = value;
                if (selectedNode != null && selectedNode.NodeType == TreeNodeType.Instrument && selectedNode.NodeName != "空")
                {
                    _eventAggregator.GetEvent<CompSelectedEvent>().Publish(selectedNode);
                    GlobalObject.CurrentCmpntID = selectedNode.Id;
                }
                else if (selectedNode != null
                    && (selectedNode.NodeType == TreeNodeType.InstrumentDoc_pd
                    || selectedNode.NodeType == TreeNodeType.InstrumentDoc_spec)
                    && selectedNode.NodeName != "空")
                {
                    _eventAggregator.GetEvent<CompSelectedEvent>().Publish(selectedNode);
                    GlobalObject.CurrentCmpntID = selectedNode.Parent.Id;//仪表节点下面的东西
                }
                else
                {
                    GlobalObject.CurrentCmpntID = "";
                }
                RaisePropertyChanged();
            }
        }

        /// <summary>
        /// 切换plant后触发
        /// </summary>
        public DelegateCommand<object> PlantSelectedCommand { get; set; }

        /// <summary>
        /// 绑定到 ContextOperationModel 的 最后一个参数 <see cref="ContextOperationModel.Command"/>
        /// </summary>
        public DelegateCommand<object> ExcuteCommand { get; set; }

        /// <summary>
        /// 树里展开后触发
        /// </summary>
        public DelegateCommand<TreeNodeModel> PreviewExpandCommand { get; set; }
        public Instruments insdata { get; private set; }


        /// <summary>
        /// 执行右键菜单点击后的功能
        /// </summary>
        /// <param name="obj"></param>
        private async void ExecContextMenu(object obj)
        {
            RadMenuItem radMenuItem = obj as RadMenuItem;
            if (radMenuItem == null)
            {
                return;
            }
            ContextOperationModel contextOperation = (obj as RadMenuItem).DataContext as ContextOperationModel;
            switch (contextOperation?.ObjectType) //相当于什么对象，做什么事情
            {
                case ObjectDefId.loop:
                    switch (contextOperation.ContextType)
                    {
                        case ContextType.Create:
                            NewOne(nameof(NewLoop));//右键，新建回路
                            break;

                        case ContextType.Copy:
                            NewOne(nameof(NewLoop));//右键,复制回路
                            break;

                        case ContextType.Delete:
                            bool deleteall = false;
                            DialogHelper.ShowQuestion(
                                _dialogService,
                                $"是否删除{contextOperation.ObjectType}:{SelectedNode.NodeName}",
                                async p =>
                                {
                                    if (p?.Result == ButtonResult.Yes)
                                    {
                                        List<Task> tasks = new List<Task>();
                                        DialogHelper.ShowQuestion(
                                            _dialogService,
                                            $"是否删除{contextOperation.ObjectType}:\n{SelectedNode.NodeName}下所有仪表！",
                                            p =>
                                            {
                                                if (p?.Result == ButtonResult.Yes)
                                                {
                                                    deleteall = true;
                                                }
                                            }
                                        );
                                        if (deleteall)
                                        {

                                            var instruments = await _instrumentService.GetInstrumentsAsync(_proId, $"loop_id='{SelectedNode.Id}' and ENG_REF_ID='0'");
                                            foreach (var item in instruments)
                                            {
                                                _ = await _instrumentService.DeleteInstrumentAsync(_proId, item.CMPNT_ID.ToString());
                                            }
                                        }
                                        await _loopService.DeleteLoopAsync(_proId, SelectedNode.Id);
                                        SelectedNode.Parent.Nodes.Remove(SelectedNode);
                                    }
                                }
                            );
                            break;

                        case ContextType.Update://查看LOOP
                            UpdateDetail(Convert.ToDecimal(SelectedNode.Id), title: DialogTitles.dialog_title_loop_property);
                            break;
                        default:
                            break;
                    }
                    break;
                case ObjectDefId.component:
                    switch (contextOperation.ContextType)
                    {
                        case ContextType.Create:
                            NewOne(nameof(NewIns));//右键，新建仪表
                            break;

                        case ContextType.Copy:
                            NewOne(nameof(NewIns));
                            break;

                        case ContextType.Delete:
                            DialogHelper.ShowQuestion(
                                _dialogService,
                                $"是否删除{contextOperation.ObjectType}:{SelectedNode.NodeName}",
                                async p =>
                                {
                                    if (p?.Result == ButtonResult.Yes)
                                    {
                                        _ = await _instrumentService.DeleteInstrumentAsync(_proId, SelectedNode.Id);
                                        SelectedNode.Parent.Nodes.Remove(SelectedNode);
                                    }
                                }
                            );
                            break;

                        case ContextType.Update: //查看属性
                            UpdateDetail(Convert.ToDecimal(SelectedNode.Id), title: DialogTitles.dialog_title_ins_property);
                            break;
                        case ContextType.PDGeneral: //新建

                            //赋予一个dwgid号
                            var task = Task.Run(async () => await _drawingService.CreatePD(selectedNode.NodeName.Replace(" ", "") + "-PD", Convert.ToDecimal(selectedNode.Id), ObjectDefId.component, 0));
                            task.Wait();
                            Dialog.ShowMessage("创建成功！");

                            //var keyValues = new NavigationParameters
                            //{
                            //    { DialogParameterKeys.Id, SelectedNode.Id },
                            //    { DialogParameterKeys.ObjectType, ObjectDefId.component }
                            //};
                            //_regionManager.RequestNavigate(RegionNames.ContentRegion, "PdGeneralEdit", keyValues);
                            break;
                        case ContextType.Spec://新建
                            var cmpntFormId = 0;
                            var existSpec = await _specServ.GetById(Convert.ToDecimal(selectedNode.Id));


                            //0.是否已经存在规格书
                            if (existSpec == null)
                            {
                                //有问题的
                                Dialog.ShowAltert("该仪表的数据（SpecSheetData缺失）有些问题。请联系管理员。");
                            }
                            else if (existSpec.SpecFormId == 0 && existSpec.DwgId == 0)
                            {
                                //1.判断是否profile里是否由formid
                                insdata = await _instrumentService.GetInstrumentAsync(GlobalObject.CurrentProject.ProjId, SelectedNode.Id);
                                ObjectDefId objectDefId;
                                switch (insdata.CMPNT_CAT_ID)
                                {
                                    case 0:
                                        objectDefId = ObjectDefId.component; break;
                                    case 12:
                                        objectDefId = ObjectDefId.HARTInstrument; break;
                                    case 14:
                                        objectDefId = ObjectDefId.softTag; break;
                                    default:
                                        //无效
                                        Dialog.ShowMessage("暂时不支持的类型。 cmpnt_cat_id = " + insdata.CMPNT_CAT_ID);
                                        return;
                                        break;
                                }
                                var TypeProfile = await _instrumentService.GetComponentFunctionTypes(GlobalObject.CurrentProject.ProjId,
                                     $"CMPNT_FUNC_TYPE_ID = '{insdata.CMPNT_FUNC_TYPE_ID}'",
                                     "CMPNT_FUNC_TYPE_ID,PROC_FUNC_ID,SPEC_FORM_ID",
                                     "CMPNT_FUNC_TYPE_ID");
                                if (TypeProfile.Count == 0)
                                {
                                    //有问题的
                                    Dialog.ShowAltert("该仪表的仪表类型（component function type表）有些问题。请联系管理员。");

                                }
                                else
                                {
                                    cmpntFormId = TypeProfile[0].SpecFormId.ToInt();
                                }
                                //2.如果么有，再弹出form list的选择界面
                                if (cmpntFormId == 0)
                                {
                                  
                                    Dialog.ShowMessage("该仪表的仪表类型中，没有分配过规格书模板，因此需要手动进行选择一个。");
                                    var formParams = new DialogParameters();
                                    formParams.Add(DialogParameterKeys.Id, insdata.PROC_FUNC_ID);
                                    Dialog.ShowDialog("FormSelect",
                                        formParams,
                                        (p) =>
                                    {

                                        if (p.Result == ButtonResult.OK)
                                        {
                                            //拿到选择的formid

                                            cmpntFormId = p.Parameters.GetValue<int>(DialogParameterKeys.Id); ;
                                        }
                                        else
                                        {
                                            //取消了
                                        }
                                    });
                                }
                                else
                                {

                                }
                                //3.最终得到
                                if (cmpntFormId != 0)
                                {
                                    var task2 = Task.Run(async () =>
                                    await _drawingService.CreateSpec(selectedNode.NodeName.Replace(" ", "") + "-SP",
                                    cmpntFormId,
                                    Convert.ToDecimal(selectedNode.Id), objectDefId, 0)
                                    );
                                    task2.Wait();
                                    Dialog.ShowMessage("创建成功！");
                                }
                                else
                                {
                                    return;
                                }


                            }
                            else
                            {
                                Dialog.ShowMessage("规格书已经存在。");
                            }

                            break;
                        default:
                            break;
                    }
                    break;

                case ObjectDefId.pd:
                    switch (contextOperation.ContextType)
                    {
                        case ContextType.Rename://文档重命名
                            Dialog.ShowMessage(ConstantString.FuncToBeContinue);
                            var createParameters = new DialogParameters();
                            createParameters.Add(DialogParameterKeys.ObjectType, ObjectDefId.pd);
                            createParameters.Add(DialogParameterKeys.Id, SelectedNode.Id);
                            createParameters.Add(DialogParameterKeys.Content, SelectedNode.NodeName);//old name
                            _dialogService.ShowDialog(nameof(Rename), createParameters, null);
                            break;
                        case ContextType.Revision://版次管理
                            var dialogParameters = new DialogParameters();
                            dialogParameters.Add(DialogParameterKeys.Id, SelectedNode.Id);
                            Dialog.ShowDialog(nameof(RevisionManager), dialogParameters, null);
                            break;
                        case ContextType.Update:
                        case ContextType.PDGeneral:
                            var keyValues = new NavigationParameters
                    {
                        { DialogParameterKeys.Id, SelectedNode.Parent.Id },
                        { DialogParameterKeys.Title, SelectedNode.NodeName},//这里是parent才是仪表id，本身id是dwgid
                        { DialogParameterKeys.ObjectType, ObjectDefId.component }
                    };

                            insdata = await _instrumentService.GetInstrumentAsync(GlobalObject.CurrentProject.ProjId, SelectedNode.Parent.Id);
                            switch (insdata.PROC_FUNC_ID)
                            {
                                case 2M:
                                    _regionManager.RequestNavigate(RegionNames.ContentRegion, "PdLevelEdit", keyValues);
                                    break;
                                default:
                                    _regionManager.RequestNavigate(RegionNames.ContentRegion, "PdGeneralEdit", keyValues);
                                    break;
                            }

                            break;
                        default:
                            break;
                    }
                    break;

                case ObjectDefId.spec:
                    switch (contextOperation.ContextType)
                    {
                        case ContextType.Revision://版次管理
                            var dialogParameters = new DialogParameters();
                            dialogParameters.Add(DialogParameterKeys.Id, SelectedNode.Id);
                            Dialog.ShowDialog(nameof(RevisionManager), dialogParameters, null);
                            break;

                        case ContextType.Update:




                            await SpecOut(SelectedNode.Parent.Id);

                            break;
                        default:
                            break;
                    }
                    break;
                default:
                    break;
            }

            //新建位号、loop的窗口
            void NewOne(string dialogName)
            {
                //find unit id
                string unitid = GlobalObject.CurrentUnit.UnitId.ToString();
                string loopid = "0";
                if (SelectedNode != null)
                {
                    switch (SelectedNode.NodeType)
                    {
                        case TreeNodeType.Loop:
                            loopid = SelectedNode.Id;
                            unitid = SelectedNode.Parent.Id;
                            break;
                        case TreeNodeType.Instrument:
                            if (SelectedNode.Parent.NodeType == TreeNodeType.Loop)
                            {
                                loopid = SelectedNode.Parent.Id;//回路下新建仪表
                                unitid = SelectedNode.Parent.Parent.Id;
                            }
                            else
                            {
                                unitid = SelectedNode.Parent.Id;
                            }
                            break;
                        case TreeNodeType.LoopFolder:
                        case TreeNodeType.InstrumentFolder:
                            unitid = SelectedNode.Id;//单元号，根据点击的文件夹来确定
                            break;
                        default:
                            break;
                    }
                }
                if (string.IsNullOrEmpty(unitid))
                {
                    return;
                }
                DialogPurpose dialogPurpose = DialogPurpose.None;
                decimal copyfromId = 0;
                string _title = $"{contextOperation.ObjectType}";
                string title = "";
                switch (contextOperation.ContextType)
                {
                    case ContextType.Create:
                        dialogPurpose = DialogPurpose.Create;
                        if (contextOperation.ObjectType == ObjectDefId.component)
                        {
                            title = DialogTitles.dialog_title_ins_Create;
                        }
                        else if (contextOperation.ObjectType == ObjectDefId.loop)
                        {
                            title = DialogTitles.dialog_title_loop_Create;
                        }
                        break;
                    case ContextType.Copy:
                        copyfromId = Convert.ToDecimal(selectedNode.Id);

                        if (contextOperation.ObjectType == ObjectDefId.component)
                        {
                            title = DialogTitles.dialog_title_ins_Duplicate + $"（从{selectedNode.NodeName}）";
                        }
                        else if (contextOperation.ObjectType == ObjectDefId.loop)
                        {
                            title = DialogTitles.dialog_title_loop_Duplicate + $"（从{selectedNode.NodeName}）";
                        }
                        //想办法把原始仪表的typeid拿过来
                        dialogPurpose = DialogPurpose.Copy;
                        break;
                    default:
                        dialogPurpose = DialogPurpose.None;
                        title = $"{_title}";
                        break;
                }
                SmartDialogParameter Parameters = new SmartDialogParameter(title: title)
                {
                    { DialogParameterKeys.ObjectType, contextOperation.ObjectType },
                    { DialogParameterKeys.Id, copyfromId },
                    { "unitId", unitid },
                    { "loopId", loopid },
                };
                _dialogService.ShowDialog(
                    dialogName,
                    Parameters,
                    p =>
                    {
                        //回调函数，相当于创建完成后，直接打开属性窗口
                        if (p.Result == ButtonResult.Yes)
                        {
                            decimal newObjId = p.Parameters.GetValue<decimal>(DialogParameterKeys.Id);
                            if (dialogName == nameof(NewIns))
                            {
                                //这个时候其实已经创建完了，和属性查看一样了
                                UpdateDetail(newObjId, DialogTitles.dialog_title_ins_property, dialogPurpose);
                            }
                            else if (dialogName == nameof(NewLoop))
                            {
                                UpdateDetail(newObjId, DialogTitles.dialog_title_loop_property, dialogPurpose);
                            }
                        }
                    }
                );
            }

            ///打开具体的属性窗口
            void UpdateDetail(decimal id, string title, DialogPurpose dialogPurpose = DialogPurpose.Update)
            {
                SmartDialogParameter createParameters = new SmartDialogParameter(title, dialogPurpose)
                {
                    { DialogParameterKeys.ObjectType, contextOperation.ObjectType },
                    { DialogParameterKeys.Id, id }
                };
                _dialogService.ShowDialog(nameof(CommonProperty), createParameters, null);
            }
        }
        /// <summary>
        /// 展示
        /// </summary>
        /// <returns></returns>
        async Task SpecOut(string CmpntID)
        {
            var rr = await _specServ.DownSpecOutputAsync(GlobalObject.CurrentProject.ProjId.ToString(), GlobalObject.CurrentProject.ProjName.ToString(), CmpntID);
            if (!rr.succeeded)
            {
                switch (rr.statusCode)
                {
                    case 400:
                    case 500:
                        //业务错误
                        Dialog.ShowAltert(rr.errors);
                        //关闭view
                        break;
                    default:
                        //网络错误
                        Dialog.ShowAltert(rr.errors);
                        LoggerHelper.Current.Error(rr.errors.ToString());
                        break;
                }
                return;
            }
            else
            {
                //这部分给 specEdit
                var keyValues = new NavigationParameters
                    {
                        { DialogParameterKeys.Id, SelectedNode.Parent.Id },//这里是parent才是仪表id，本身id是dwgid
                        { "Dwgid", SelectedNode.Id },
                        { DialogParameterKeys.ObjectType, ObjectDefId.component },
                            {DialogParameterKeys.Content,rr.data },
                              {DialogParameterKeys.Title,selectedNode.NodeName }
                    };
                var dialogParameters = new DialogParameters();
                dialogParameters.Add(DialogParameterKeys.Id, SelectedNode.Id);
                _regionManager.RequestNavigate(RegionNames.ContentRegion, "SpecEdit", keyValues);
                //var bytes = Convert.FromBase64String(rr.data.Data);//server端正好是用的ToBase64String，把byte[]变为的string
                //var memoryStream = new MemoryStream(bytes);
                //return new RESTfulResult<Stream> { data = memoryStream, succeeded = true };
            }



        }
        /// <summary>
        /// 右键菜单模块，从xaml的代码里，通过datacontext来调用到viewmodel里
        /// </summary>
        /// <param name="actionItem"></param>
        internal void PreapreContextMenu(TreeNodeModel actionItem)
        {
            if (actionItem != null)
            {
                this.ContextOperations = GetContextoperations(actionItem.NodeType);
            }
            else
            {
                this.ContextOperations = GetContextoperations(TreeNodeType.Plant);
            }
            // 局部方法 local method，在一个方法里，嵌套定义了另外一个方法
            ObservableCollection<ContextOperationModel> GetContextoperations(TreeNodeType itemType)
            {
                ObservableCollection<ContextOperationModel> menus = new ObservableCollection<ContextOperationModel>();
                switch (itemType)
                {
                    case TreeNodeType.Loop:
                        menus = new ObservableCollection<ContextOperationModel>
                        {
                            new ContextOperationModel("新建仪表...", ContextType.Create, ObjectDefId.component, ExcuteCommand),
                            new ContextOperationModel("复制回路...", ContextType.Copy, ObjectDefId.loop, ExcuteCommand),
                            new ContextOperationModel("删除回路...", ContextType.Delete, ObjectDefId.loop, ExcuteCommand),
                            new ContextOperationModel("回路属性...", ContextType.Update, ObjectDefId.loop, ExcuteCommand)

                        };
                        return menus;

                    case TreeNodeType.Instrument:
                        menus = new ObservableCollection<ContextOperationModel>
                        {
                            //new ContextOperationModel( "新建仪表...",ContextType.Create,ObjectType.Instrument,ExcuteCommand),
                            new ContextOperationModel("复制仪表...", ContextType.Copy, ObjectDefId.component, ExcuteCommand),
                            new ContextOperationModel("删除仪表...", ContextType.Delete, ObjectDefId.component, ExcuteCommand),
                            new ContextOperationModel("仪表属性...", ContextType.Update, ObjectDefId.component, ExcuteCommand),
                            //new ContextOperationModel("新建/打开规格书...", ContextType.Create, ObjectDefId.component, ExcuteCommand),
                            new ContextOperationModel("新建工艺参数表...", ContextType.PDGeneral, ObjectDefId.component, ExcuteCommand),
                            new ContextOperationModel("新建规格书...", ContextType.Spec, ObjectDefId.component, ExcuteCommand)
                        };
                        return menus;

                    case TreeNodeType.LoopFolder:
                        menus = new ObservableCollection<ContextOperationModel>
                        {
                            new ContextOperationModel("新建回路...", ContextType.Create, ObjectDefId.loop, ExcuteCommand),
                                  new ContextOperationModel("过滤...", ContextType.ApplyFilter, ObjectDefId.loop, ExcuteCommand),
                              new ContextOperationModel("取消过滤...", ContextType.UnApplyFilter, ObjectDefId.loop, ExcuteCommand)
                        };
                        return menus;

                    case TreeNodeType.InstrumentFolder:
                        menus = new ObservableCollection<ContextOperationModel>
                        {
                            new ContextOperationModel("新建仪表...", ContextType.Create, ObjectDefId.component, ExcuteCommand),
                                new ContextOperationModel("过滤...", ContextType.ApplyFilter, ObjectDefId.component, ExcuteCommand),
                              new ContextOperationModel("取消过滤...", ContextType.UnApplyFilter, ObjectDefId.component, ExcuteCommand)
                              
                        };
                        return menus;
                    case TreeNodeType.InstrumentDoc_spec:
                        menus = new ObservableCollection<ContextOperationModel>
                        {
                            new ContextOperationModel("打开数据表", ContextType.Update, ObjectDefId.spec, ExcuteCommand),
                            new ContextOperationModel("版次管理", ContextType.Revision, ObjectDefId.pd, ExcuteCommand)
                        };
                        return menus;
                    case TreeNodeType.InstrumentDoc_pd:
                        menus = new ObservableCollection<ContextOperationModel>
                        {
                            new ContextOperationModel("打开工艺参数表", ContextType.Update, ObjectDefId.pd, ExcuteCommand),
                            new ContextOperationModel("修改文档名字", ContextType.Rename, ObjectDefId.pd, ExcuteCommand),
                            new ContextOperationModel("版次管理", ContextType.Revision, ObjectDefId.pd, ExcuteCommand)
                        };
                        return menus;

                    default:
                        return new ObservableCollection<ContextOperationModel>();
                }
            }
        }

        /// <summary>
        /// 展开加载模块
        /// </summary>
        /// <param name="obj"></param>
        public async void PreviewExpandAsync(TreeNodeModel obj)
        {
            switch (obj.NodeType)
            {
                case TreeNodeType.Panel_DPFolder:
                    TreeNodes.BeginUpdate();
                    var dp = await _panelServ.GetAsync(_proId, selectedPlant.PLANT_ID, panel_category_id.dp);

                    while (obj.Nodes.Any())
                    {
                        obj.Nodes.RemoveAt(0);
                    }
                    foreach (var pid in dp)
                    {
                        var pidNode = new TreeNodeModel(TreeNodes, obj, true)
                        {
                            NodeName = pid.PanelName,
                            Id = pid.PanelId.ToString(),
                            NodeType = TreeNodeType.Panel_DCS
                        };
                        obj.Nodes.Add(pidNode);
                    }
                    if (!obj.Nodes.Any())
                    {
                        //空节点
                        var emptyloopNode = new TreeNodeModel(TreeNodes, obj) { NodeType = TreeNodeType.Blank };
                        obj.Nodes.Add(emptyloopNode);
                    }
                    TreeNodes.EndUpdate();
                    break;
                case TreeNodeType.Panel_JBFolder:
                    TreeNodes.BeginUpdate();
                    var jb = await _panelServ.GetAsync(_proId, selectedPlant.PLANT_ID, panel_category_id.jb);

                    while (obj.Nodes.Any())
                    {
                        obj.Nodes.RemoveAt(0);
                    }
                    foreach (var pid in jb)
                    {
                        var pidNode = new TreeNodeModel(TreeNodes, obj, true)
                        {
                            NodeName = pid.PanelName,
                            Id = pid.PanelId.ToString(),
                            NodeType = TreeNodeType.Panel_DCS
                        };
                        obj.Nodes.Add(pidNode);
                    }
                    if (!obj.Nodes.Any())
                    {
                        //空节点
                        var emptyloopNode = new TreeNodeModel(TreeNodes, obj) { NodeType = TreeNodeType.Blank };
                        obj.Nodes.Add(emptyloopNode);
                    }
                    TreeNodes.EndUpdate();
                    break;
                case TreeNodeType.Panel_MRFolder:
                    TreeNodes.BeginUpdate();
                    var mr = await _panelServ.GetAsync(_proId, selectedPlant.PLANT_ID, panel_category_id.mr);

                    while (obj.Nodes.Any())
                    {
                        obj.Nodes.RemoveAt(0);
                    }
                    foreach (var pid in mr)
                    {
                        var pidNode = new TreeNodeModel(TreeNodes, obj, true)
                        {
                            NodeName = pid.PanelName,
                            Id = pid.PanelId.ToString(),
                            NodeType = TreeNodeType.Panel_DCS
                        };
                        obj.Nodes.Add(pidNode);
                    }
                    if (!obj.Nodes.Any())
                    {
                        //空节点
                        var emptyloopNode = new TreeNodeModel(TreeNodes, obj) { NodeType = TreeNodeType.Blank };
                        obj.Nodes.Add(emptyloopNode);
                    }
                    TreeNodes.EndUpdate();
                    break;
                case TreeNodeType.Panel_DCSFolder:
                    TreeNodes.BeginUpdate();
                    var dcss = await _panelServ.GetAsync(_proId, selectedPlant.PLANT_ID, panel_category_id.dcs);

                    while (obj.Nodes.Any())
                    {
                        obj.Nodes.RemoveAt(0);
                    }
                    foreach (var pid in dcss)
                    {
                        var pidNode = new TreeNodeModel(TreeNodes, obj, true)
                        {
                            NodeName = pid.PanelName,
                            Id = pid.PanelId.ToString(),
                            NodeType = TreeNodeType.Panel_DCS
                        };
                        obj.Nodes.Add(pidNode);
                    }
                    if (!obj.Nodes.Any())
                    {
                        //空节点
                        var emptyloopNode = new TreeNodeModel(TreeNodes, obj) { NodeType = TreeNodeType.Blank };
                        obj.Nodes.Add(emptyloopNode);
                    }
                    TreeNodes.EndUpdate();
                    break;
                case TreeNodeType.Equip:
                    TreeNodes.BeginUpdate();
                    var equipInstruments = await _instrumentService.GetInstrumentsAsync(_proId, $"equip_id='{obj.Id}' and ENG_REF_ID='0'", orderby: "CMPNT_NAME");

                    while (obj.Nodes.Any())
                    {
                        obj.Nodes.RemoveAt(0);
                    }
                    foreach (var pid in equipInstruments)
                    {
                        var pidNode = new TreeNodeModel(TreeNodes, obj, true)
                        {
                            NodeName = pid.CMPNT_NAME,
                            Id = pid.CMPNT_ID.ToString(),
                            NodeType = TreeNodeType.Instrument
                        };
                        obj.Nodes.Add(pidNode);
                    }
                    if (!obj.Nodes.Any())
                    {
                        //空节点
                        var emptyloopNode = new TreeNodeModel(TreeNodes, obj) { NodeType = TreeNodeType.Blank };
                        obj.Nodes.Add(emptyloopNode);
                    }
                    TreeNodes.EndUpdate();
                    break;
                case TreeNodeType.EquipFolder:
                    TreeNodes.BeginUpdate();
                    var equips = await _equipServ.GetEquipsAsync(_proId, selectedPlant.PLANT_ID);


                    while (obj.Nodes.Any())
                    {
                        obj.Nodes.RemoveAt(0);
                    }
                    foreach (var pid in equips)
                    {
                        var pidNode = new TreeNodeModel(TreeNodes, obj, true)
                        {
                            NodeName = pid.EquipName,
                            Id = pid.EquipId.ToString(),
                            NodeType = TreeNodeType.Equip
                        };
                        obj.Nodes.Add(pidNode);
                    }
                    if (!obj.Nodes.Any())
                    {
                        //空节点
                        var emptyloopNode = new TreeNodeModel(TreeNodes, obj) { NodeType = TreeNodeType.Blank };
                        obj.Nodes.Add(emptyloopNode);
                    }
                    TreeNodes.EndUpdate();
                    break;

                case TreeNodeType.Line:
                    TreeNodes.BeginUpdate();
                    var lineInstruments = await _instrumentService.GetInstrumentsAsync(_proId, $"line_id='{obj.Id}' and ENG_REF_ID='0'", orderby: "CMPNT_NAME");

                    while (obj.Nodes.Any())
                    {
                        obj.Nodes.RemoveAt(0);
                    }
                    foreach (var pid in lineInstruments)
                    {
                        var pidNode = new TreeNodeModel(TreeNodes, obj, true)
                        {
                            NodeName = pid.CMPNT_NAME,
                            Id = pid.CMPNT_ID.ToString(),
                            NodeType = TreeNodeType.Instrument
                        };
                        obj.Nodes.Add(pidNode);
                    }
                    if (!obj.Nodes.Any())
                    {
                        //空节点
                        var emptyloopNode = new TreeNodeModel(TreeNodes, obj) { NodeType = TreeNodeType.Blank };
                        obj.Nodes.Add(emptyloopNode);
                    }
                    TreeNodes.EndUpdate();
                    break;
                case TreeNodeType.LineFolder:
                    TreeNodes.BeginUpdate();
                    var lines = await _lineServ.GetLinesTreeAsync(_proId, selectedPlant.PLANT_ID);


                    while (obj.Nodes.Any())
                    {
                        obj.Nodes.RemoveAt(0);
                    }
                    foreach (var pid in lines)
                    {
                        var pidNode = new TreeNodeModel(TreeNodes, obj, true)
                        {
                            NodeName = pid.LineNum,
                            Id = pid.LineId.ToString(),
                            NodeType = TreeNodeType.Line
                        };
                        obj.Nodes.Add(pidNode);
                    }
                    if (!obj.Nodes.Any())
                    {
                        //空节点
                        var emptyloopNode = new TreeNodeModel(TreeNodes, obj) { NodeType = TreeNodeType.Blank };
                        obj.Nodes.Add(emptyloopNode);
                    }
                    TreeNodes.EndUpdate();
                    break;
                case TreeNodeType.PID:
                    TreeNodes.BeginUpdate();
                    var pidInstruments = await _instrumentService.GetInstrumentsAsync(_proId, $"dwg_id='{obj.Id}' and ENG_REF_ID='0'", orderby: "CMPNT_NAME");


                    while (obj.Nodes.Any())
                    {
                        obj.Nodes.RemoveAt(0);
                    }
                    foreach (var pid in pidInstruments)
                    {
                        var pidNode = new TreeNodeModel(TreeNodes, obj, true)
                        {
                            NodeName = pid.CMPNT_NAME,
                            Id = pid.CMPNT_ID.ToString(),
                            NodeType = TreeNodeType.Instrument
                        };
                        obj.Nodes.Add(pidNode);
                    }
                    if (!obj.Nodes.Any())
                    {
                        //空节点
                        var emptyloopNode = new TreeNodeModel(TreeNodes, obj) { NodeType = TreeNodeType.Blank };
                        obj.Nodes.Add(emptyloopNode);
                    }
                    TreeNodes.EndUpdate();
                    break;
                case TreeNodeType.PIDFolder:
                    TreeNodes.BeginUpdate();
                    var PIDS = await _drawingService.GetPIDAsync(_proId, selectedPlant.PLANT_ID);
                    while (obj.Nodes.Any())
                    {
                        obj.Nodes.RemoveAt(0);
                    }
                    foreach (var pid in PIDS)
                    {
                        var pidNode = new TreeNodeModel(TreeNodes, obj, true)
                        {
                            NodeName = pid.DwgName,
                            Id = pid.DwgId.ToString(),
                            NodeType = TreeNodeType.PID
                        };
                        obj.Nodes.Add(pidNode);
                    }
                    if (!obj.Nodes.Any())
                    {
                        //空节点
                        var emptyloopNode = new TreeNodeModel(TreeNodes, obj) { NodeType = TreeNodeType.Blank };
                        obj.Nodes.Add(emptyloopNode);
                    }
                    TreeNodes.EndUpdate();
                    break;
                case TreeNodeType.LoopFolder:
                    TreeNodes.BeginUpdate();
                    var loops = await _loopService.GetUnitLoopsAsync(_proId, obj.Id);//unit id
                    while (obj.Nodes.Any())
                    {
                        obj.Nodes.RemoveAt(0);
                    }
                    foreach (var loop in loops)
                    {
                        var loopNode = new TreeNodeModel(TreeNodes, obj)
                        {
                            NodeName = loop.LOOP_NAME,
                            Id = loop.LOOP_ID.ToString(),
                            NodeType = TreeNodeType.Loop
                        };
                        var emptyinsNode = new TreeNodeModel(TreeNodes, loopNode) { NodeType = TreeNodeType.Instrument };
                        loopNode.Nodes.Add(emptyinsNode);
                        obj.Nodes.Add(loopNode);
                    }
                    if (!obj.Nodes.Any())
                    {
                        var emptyloopNode = new TreeNodeModel(TreeNodes, obj) { NodeType = TreeNodeType.Loop };
                        obj.Nodes.Add(emptyloopNode);
                    }
                    TreeNodes.EndUpdate();
                    break;

                case TreeNodeType.InstrumentFolder:
                    TreeNodes.BeginUpdate();
                    var unitInstruments = await _instrumentService.GetInstrumentsAsync(_proId, $"unit_id='{obj.Id}' and ENG_REF_ID='0'", orderby: "CMPNT_NAME");
                    while (obj.Nodes.Any())
                    {
                        obj.Nodes.RemoveAt(0);
                    }
                    foreach (Instruments instr in unitInstruments)
                    {
                        var insNode = new TreeNodeModel(TreeNodes, obj)
                        {
                            NodeName = instr.CMPNT_NAME,
                            Id = instr.CMPNT_ID.ToString(),
                            NodeType = TreeNodeType.Instrument
                        };
                        var insDoc = new TreeNodeModel(TreeNodes, insNode) { NodeType = TreeNodeType.Blank };
                        insNode.Nodes.Add(insDoc);
                        obj.Nodes.Add(insNode);
                    }
                    if (!obj.Nodes.Any())
                    {
                        var emptyinsNode = new TreeNodeModel(TreeNodes, obj) { NodeType = TreeNodeType.Blank };
                        obj.Nodes.Add(emptyinsNode);
                    }
                    TreeNodes.EndUpdate();
                    break;

                case TreeNodeType.Loop:
                    TreeNodes.BeginUpdate();

                    var loopInstruments = await _instrumentService.GetInstrumentsAsync(_proId, $"loop_id='{obj.Id}' and ENG_REF_ID='0'");
                    while (obj.Nodes.Any())
                    {
                        obj.Nodes.RemoveAt(0);
                    }
                    foreach (Instruments instr in loopInstruments)
                    {
                        var insNode = new TreeNodeModel(TreeNodes, obj)
                        {
                            NodeName = instr.CMPNT_NAME,
                            Id = instr.CMPNT_ID.ToString(),
                            NodeType = TreeNodeType.Instrument
                        };
                        var insDoc = new TreeNodeModel(TreeNodes, insNode) { NodeType = TreeNodeType.Blank };
                        insNode.Nodes.Add(insDoc);
                        obj.Nodes.Add(insNode);
                    }
                    if (!obj.Nodes.Any())
                    {
                        var emptyinsNode = new TreeNodeModel(TreeNodes, obj) { NodeType = TreeNodeType.Blank };
                        obj.Nodes.Add(emptyinsNode);
                    }
                    TreeNodes.EndUpdate();
                    break;

                case TreeNodeType.Instrument:
                    TreeNodes.BeginUpdate();
                    List<Drawing> doc_spec = await _projectService.QueryBySQL1<Drawing>(
                        _proId,
                        $"select t2.dwg_id DwgId,t2.dwg_name DwgName from spec_sheet_data t1 join drawing t2 on t1.dwg_id=t2.dwg_id where t1.cmpnt_id={obj.Id} and t2.dwg_id != 0",
                        SchemaLevel.domain
                    );
                    List<Drawing> doc_pd = await _projectService.QueryBySQL1<Drawing>(
                       _proId,
                       $"select t2.dwg_id DwgId,t2.dwg_name DwgName from pd_general t1 join drawing t2 on t1.dwg_id=t2.dwg_id where t1.cmpnt_id={obj.Id} and t2.dwg_id != 0",
                       SchemaLevel.domain
                   );
                    while (obj.Nodes.Any())
                    {
                        obj.Nodes.RemoveAt(0);
                    }
                    foreach (Drawing specdoc in doc_spec)
                    {
                        var insNode = new TreeNodeModel(TreeNodes, obj)
                        {
                            NodeName = specdoc.DwgName,
                            Id = specdoc.DwgId.ToString(),
                            NodeType = TreeNodeType.InstrumentDoc_spec
                        };
                        obj.Nodes.Add(insNode);
                    }
                    foreach (Drawing specdoc in doc_pd)
                    {

                        var insNode = new TreeNodeModel(TreeNodes, obj)
                        {
                            NodeName = specdoc.DwgName,
                            Id = specdoc.DwgId.ToString(),
                            NodeType = TreeNodeType.InstrumentDoc_pd
                        };
                        obj.Nodes.Add(insNode);
                    }
                    if (!obj.Nodes.Any())
                    {
                        var emptyinsNode = new TreeNodeModel(TreeNodes, obj) { NodeType = TreeNodeType.Blank };
                        obj.Nodes.Add(emptyinsNode);
                    }
                    TreeNodes.EndUpdate();
                    break;


                default:
                    break;
            }
            Console.WriteLine(obj.GetType());
        }

        private void ReSelectProjectDomain(Project pro)
        {
            OnInitPage(null);
        }

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="pro">参数在xaml里通过 combobox控件的SelectedItem 带进来</param>
        private void PlantSelectedAsync(object obj)
        {
            var args = obj as System.Windows.Controls.SelectionChangedEventArgs;
            if (args == null)
            {
                return;
            }
            if (args.AddedItems.Count < 1) return;

            Plant pro = args.AddedItems[0] as Plant;
            InitTree(pro);
        }

        protected override async void OnInitPage(object obj)
        {
            _proId = GlobalObject.CurrentProject.ProjId;
            //GlobalObject.Plants = await _plantGroupService.GetPlantGroupTreeAsync(_proId.ToString());//初始化一次就行了
            Plants.Clear();//避免越来越多
            selectedPlant = null;
            foreach (var plant in GlobalObject.Plants)
            {
                Plants.Add(plant);
            }
            //Plants.AddRange(GlobalObject.Plants);
            var plandid = GlobalObject.CurrentUnit.PlantId;
            selectedPlant = GlobalObject.Plants.FirstOrDefault(x => x.PLANT_ID == plandid);
            if (selectedPlant == null)
            {
                selectedPlant = GlobalObject.Plants.FirstOrDefault();
            }
            InitTree(selectedPlant);
        }
        /// <summary>
        /// 初始化渲染pau的tree
        /// </summary>
        /// <param name="pro"></param>
        private void InitTree(Plant pro)
        {

            TreeNodes.Clear();
            TreeNodes.BeginUpdate();
            var plantNode = new TreeNodeModel(TreeNodes, null)
            {
                NodeName = pro.PlantName,
                Id = pro.PLANT_ID.ToString(),
                NodeType = TreeNodeType.Plant
            };
            if (pro.Area != null)
            {
                foreach (var area in pro.Area)
                {
                    var areaNode = new TreeNodeModel(TreeNodes, plantNode)
                    {
                        NodeName = area.AreaName,
                        Id = area.AreaId.ToString(),
                        NodeType = TreeNodeType.Area
                    };

                    if (area.Unit != null)
                    {
                        foreach (var unit in area.Unit)
                        {
                            var unitNode = new TreeNodeModel(TreeNodes, areaNode)
                            {
                                NodeName = unit.UnitName,
                                Id = unit.UnitId.ToString(),
                                NodeType = TreeNodeType.Unit
                            };
                            #region 增加unit下的loop和ins文件夹
                            var loopfolderNode = new TreeNodeModel(TreeNodes, unitNode)
                            {
                                NodeName = "Loops",
                                Id = unit.UnitId.ToString(),
                                NodeType = TreeNodeType.LoopFolder
                            };
                            var insfolderNode = new TreeNodeModel(TreeNodes, unitNode)
                            {
                                NodeName = "Instruments",
                                Id = unit.UnitId.ToString(),
                                NodeType = TreeNodeType.InstrumentFolder
                            };

                            var loopNode = new TreeNodeModel(TreeNodes, loopfolderNode) { NodeType = TreeNodeType.Loop };
                            var insNode = new TreeNodeModel(TreeNodes, insfolderNode) { NodeType = TreeNodeType.Instrument };
                            insfolderNode.Nodes.Add(insNode);
                            loopfolderNode.Nodes.Add(loopNode);
                            #endregion

                            unitNode.Nodes.Add(loopfolderNode);
                            unitNode.Nodes.Add(insfolderNode);
                            areaNode.Nodes.Add(unitNode);
                        }
                    }

                    plantNode.Nodes.Add(areaNode);
                }
            }

            #region Extra
            var equipFolderNode = new TreeNodeModel(TreeNodes, plantNode, true)
            {
                NodeName = "工艺设备",
                Id = "",
                NodeType = TreeNodeType.EquipFolder
            };
            plantNode.Nodes.Add(equipFolderNode);
            var lineFolderNode = new TreeNodeModel(TreeNodes, plantNode, true)
            {
                NodeName = "管线号",
                Id = "",
                NodeType = TreeNodeType.LineFolder
            };
            plantNode.Nodes.Add(lineFolderNode);
            var pidFolderNode = new TreeNodeModel(TreeNodes, plantNode, true)
            {
                NodeName = "P&ID图",
                Id = "",
                NodeType = TreeNodeType.PIDFolder
            };
            plantNode.Nodes.Add(pidFolderNode);
            var HKNode = new TreeNodeModel(TreeNodes, plantNode, true)
            {
                NodeName = "安装图",
                Id = "",
                NodeType = TreeNodeType.HookUpFolder
            };
            plantNode.Nodes.Add(HKNode);
            var cableFolderNode = new TreeNodeModel(TreeNodes, plantNode)
            {
                NodeName = "电缆",
                Id = "",
                NodeType = TreeNodeType.CableFolder
            };
            var deviceCableFolderNode = new TreeNodeModel(TreeNodes, cableFolderNode, true)
            {
                NodeName = "分支电缆",
                Id = "",
                NodeType = TreeNodeType.DeviceCableFolder
            };
            var NoDeviceCableFolderNode = new TreeNodeModel(TreeNodes, cableFolderNode, true)
            {
                NodeName = "非分支电缆",
                Id = "",
                NodeType = TreeNodeType.NoDeviceCableFolder
            };
            cableFolderNode.Nodes.Add(deviceCableFolderNode);
            cableFolderNode.Nodes.Add(NoDeviceCableFolderNode);
            plantNode.Nodes.Add(cableFolderNode);

            var panelFolderNode = new TreeNodeModel(TreeNodes, plantNode)
            {
                NodeName = "接线设备(Panel)",
                Id = "",
                NodeType = TreeNodeType.PanelFolder
            };
            var panel_DPFolderNode = new TreeNodeModel(TreeNodes, cableFolderNode, true)
            {
                NodeName = "端子盒(Device Panel)",
                Id = "",
                NodeType = TreeNodeType.Panel_DPFolder
            };
            panelFolderNode.Nodes.Add(panel_DPFolderNode);
            var panel_JBFolderNode = new TreeNodeModel(TreeNodes, cableFolderNode, true)
            {
                NodeName = "接线箱",
                Id = "",
                NodeType = TreeNodeType.Panel_JBFolder
            };
            panelFolderNode.Nodes.Add(panel_JBFolderNode);
            var panel_MRFolderNode = new TreeNodeModel(TreeNodes, cableFolderNode, true)
            {
                NodeName = "中间端子柜",
                Id = "",
                NodeType = TreeNodeType.Panel_MRFolder
            };
            panelFolderNode.Nodes.Add(panel_MRFolderNode);
            var panel_DCSFolderNode = new TreeNodeModel(TreeNodes, cableFolderNode, true)
            {
                NodeName = "DCS",
                Id = "",
                NodeType = TreeNodeType.Panel_DCSFolder
            };
            panelFolderNode.Nodes.Add(panel_DCSFolderNode);
            plantNode.Nodes.Add(panelFolderNode);
            #endregion
            TreeNodes.Add(plantNode);
            TreeNodes.EndUpdate();
        }
    }
}
